package ua.yandex.sumofseries.threads;

import java.util.logging.Level;
import java.util.logging.Logger;

public class Sum {

    double sum(double n, int m) {
        Thread[] t = new Thread[m];
        MyRunnable[] r = new MyRunnable[m];
        double temp = 2 * n / m;
        double k = -n;
        for (int i = 0; i < m; i++) {
            r[i] = new MyRunnable(k, k + temp);
            t[i] = new Thread(r[i]);
            t[i].setName("thread" + i);
            t[i].start();
            k += temp;
        }
        for (int i = 0; i < m; i++) {
            try {
                t[i].join();
            } catch (InterruptedException ex) {
                Logger.getLogger(Sum.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        double sum = 0;
        for (int i = 0; i < m; i++) {
            sum += r[i].get();
        }
        sum += Math.sin(n) * Math.cos(n);
        return sum;

    }

    public void dependenceTimeAndNumberOfThreads(double n) {
        final int MAX = 50;
        for (int i = 1; i <= MAX; i++) {
            long timeout = System.currentTimeMillis();
            sum(n, i);
            System.out.print("AmountOfThreads =" + i);
            System.out.print("  Time = ");
            System.out.println(System.currentTimeMillis() - timeout);
        }
    }

    public class MyRunnable implements Runnable {

        private final double step = 0.0001;
        private double s;
        private final double start;
        private final double end;

        MyRunnable(double st, double e) {
            start = st;
            end = e;
        }

        @Override
        public void run() {
            for (double counter = start; counter < end; counter += step) {
                s += Math.sin(counter) * Math.cos(counter);
            }
        }

        public double get() {
            return s;
        }
    }
}
